﻿using System.Runtime.Serialization;
using Game.Common;
using Game.Common.Resources;
using Game.Terrain;

namespace Game.Types
{
    /// <summary>
    /// An object that can be placed on fields. Roads, pipelines and ditches are examples of objects.
    /// </summary>
    [DataContract(Namespace="game")]
    public class ObjectType : MapItemType
    {
        int _Armor;
        ObjectOrientation _ObjectOrientation;
        GameResources _BuildCost;
        BuildingType _BuildingType;
        TerrainBit _TerrainBit;
        
        int _AttackBonusPlus;
        int _AttackBonusAbsolute;
        
        int _DefenseBonusPlus;
        int _DefenseBonusAbsolute;
        
        public ObjectType()
        {
        }
        
        [OnDeserialized]
        public void OnDeserialized2(StreamingContext c)
        {
            object obj = ResourceLocator.GameResourceLocator.Get(Url);
            var t = obj as ObjectType;
            if (t != null)
            {
                _Armor = t.Armor;
                _ObjectOrientation = t.ObjectOrientation;
                _BuildCost = t.BuildCost;
                _AttackBonusPlus = t.AttackBonusPlus;
                _AttackBonusAbsolute = t.AttackBonusAbsolute;
                _DefenseBonusPlus = t.DefenseBonusPlus;
                _DefenseBonusAbsolute = t.AttackBonusAbsolute;
                _BuildingType = t.BuildingType;
                _TerrainBit = t.TerrainBit;
            }
        }
        
        public ObjectType(ObjectTypeBuilder builder)
            : base(builder)
        {
            _Armor = builder.Armor;
            _BuildCost = builder.BuildCost;
            _ObjectOrientation = builder.ObjectOrientation;
            _AttackBonusPlus = builder.AttackBonusPlus;
            _AttackBonusAbsolute = builder.AttackBonusAbsolute;
            _DefenseBonusPlus = builder.DefenseBonusPlus;
            _DefenseBonusAbsolute = builder.AttackBonusAbsolute;
            _BuildingType = builder.BuildingType;
            _TerrainBit = builder.TerrainBit;
        }
        
        /// <summary>
        /// if an object should not be attackable, set armor to 0
        /// </summary>
        public int Armor
        {
            get { return _Armor; }
        }
        
        /// <summary>
        /// The resources required to construct the object with 
        /// a unit; Note that units usually don't have any energy 
        /// available
        /// </summary>
        public GameResources BuildCost
        {
            get { return _BuildCost; }
        }

        public TerrainBit TerrainBit
        {
            get { return _TerrainBit; }
        }

        public ObjectOrientation ObjectOrientation
        {
            get { return _ObjectOrientation; }
        }
        
        /// <summary>
        /// this is added to the current attackbonus 
        /// of the field to form the new attackbonus.
        /// </summary>
        public int AttackBonusPlus
        {
            get { return _AttackBonusPlus; }
        }
        
        /// <summary>
        /// The attackbonus_abs replaces the current attackbonus of the 
        /// field by a new one. A value of -1 won't affect the attackbonus of the field
        /// </summary>
        public int AttackBonusAbsolute
        {
            get { return _AttackBonusAbsolute; }
        }

        /// <summary>
        /// this is added to the current defensebonus of the field 
        /// to form the new defensebonus.
        /// </summary>
        public int DefenseBonusPlus
        {
            get { return _DefenseBonusPlus; }
        }
        
        /// <summary>
        /// The defensebonus_abs replaces the current defensebonus of the field by a 
        /// new one. A value of -1 won't affect the attackbonus of the field
        /// </summary>
        public int DefenseBonusAbsolute
        {
            get { return _DefenseBonusAbsolute; }
        }
        
        public BuildingType BuildingType
        {
            get { return _BuildingType; }
        }
    }
    
    public class ObjectTypeBuilder : ContainerBaseTypeBuilder
    {
        GameResources _BuildCost = new GameResources();

        public ObjectTypeBuilder()
        {
            AttackBonusAbsolute= -1;
            DefenseBonusAbsolute = -1;
        }

        public int Armor {get; set;}
        
        public ObjectOrientation ObjectOrientation { get; set; }
        
        public BuildingType BuildingType { get; set; }

        public TerrainBit TerrainBit { get; set; }

        public int AttackBonusAbsolute { get; set; }

        public int AttackBonusPlus { get; set; }

        public int DefenseBonusAbsolute { get; set; }

        public int DefenseBonusPlus { get; set; }

        public GameResources BuildCost
        {
            get { return _BuildCost; }
            set { _BuildCost = value; }
        }

        public ObjectType BuildObjectType()
        {
            return new ObjectType(this);
        }
        
        public override string TypeName 
        {
            get { return "object"; }
        }

    }
    
}
